﻿using KAs.Common.Attr;
using KAs.SqlSugar.Entity;
using SqlSugar;
using System.Linq.Expressions;
using System.Reflection;

namespace KAs.SqlSugar;

/// <summary>
/// 基础仓储
/// </summary>
/// <typeparam name="T">实体类</typeparam>
/// <typeparam name="TPrimaryKey"></typeparam>
/// <remarks>
/// 自定义方法封装
/// </remarks>
public class Repository<T, TPrimaryKey> : SimpleClient<T>, IRepository<T, TPrimaryKey> where T : Entity<TPrimaryKey>, new()
{
    public Repository(ISqlSugarClient context) : base(context)
    {
        Context = context;
    }

    #region 新增
    public virtual async Task<long> InsertReturnIdAsync(T insertObj)
    {
        return await Context.Insertable(insertObj).ExcutedReturnIdAsync<T, TPrimaryKey>();
    }

    public override async Task<T> InsertReturnEntityAsync(T insertObj)
    {
        //只有添加自动审计特性的实体才会处理自动审计过程
        var diffLogFlag = typeof(T).GetCustomAttribute<AutoAuditAttribute>() != null;
        return await Context.Insertable(insertObj).EnableDiffLogEvent(diffLogFlag).ExecuteReturnEntityAsync();
    }
    #endregion

    #region 更新

    public override async Task<bool> UpdateAsync(T updateObj)
    {
        return await Context.Updateable(updateObj).ExecuteCommandAndLogDiffAsync();
    }

    public override async Task<bool> UpdateRangeAsync(T[] updateObjs)
    {
        return await Context.Updateable(updateObjs).ExecuteCommandAndLogDiffAsync();
    }

    public override async Task<bool> UpdateRangeAsync(List<T> updateObjs)
    {
        return await Context.Updateable(updateObjs).ExecuteCommandAndLogDiffAsync();
    }

    public override async Task<bool> UpdateAsync(Expression<Func<T, T>> columns, Expression<Func<T, bool>> whereExpression)
    {
        return await Context.Updateable<T>()
            .SetColumns(columns)
            .Where(whereExpression)
            .ExecuteCommandAndLogDiffAsync();
    }

    #endregion

    #region 删除
    public virtual async Task<bool> DeleteInAsync(TPrimaryKey id)
    {
        return await Context.Deleteable<T>().DeleteInAsync(id);
    }
    #endregion


    public virtual string GetDbColumnName(string propertyName)
    {
        return Context.EntityMaintenance.GetDbColumnName<T>(propertyName);
    }
}
